package com.flyan.danmuhunter.common.utils;

import cn.hutool.core.thread.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**
 * 线程工具类，提供了机器 CPU 数量的线程池，需要线程并发处理时候，统一提交到线程池里。
 * 使用了动创建线程池 ThreadPoolExecutor 的方式，以便规范的使用线程池。
 *
 * @author Flyan
 * @version 1.1
 * @date 2022/4/21 10:37
 */
public class ThreadUtil {

    /**
     * Max number of threads(Number of CPU).
     */
    public static final int MAX_THREADS = Runtime.getRuntime().availableProcessors();

    /**
     * Core number of threads that it's computed from ${MAX_THREAD}
     */
    public static final int CORE_POOL_SIZE = (int) (MAX_THREADS * 0.5);

    /**
     * When the number of threads is greater than
     * the core, this is the maximum time that excess idle threads
     * will wait for new tasks before terminating.
     */
    public static final long KEEP_ALIVE_TIME = 3;

    /**
     * The time unit for the ${KEEP_ALIVE_TIME} argument.
     */
    public static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;

    /**
     * The queue to use for holding tasks before they are
     * executed.  This queue will hold only the {@code Runnable}
     * tasks submitted by the {@code execute} method.
     */
    private static final BlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(CORE_POOL_SIZE);

    /**
     * Throws a RejectedExecutionException to Rejected tasks.
     */
    private static final RejectedExecutionHandler REJECTED_EXECUTION_HANDLER = new ThreadPoolExecutor.AbortPolicy();

    /**
     * Giving a name to thread of thread pool.
     */
    private static final ThreadFactory NAMED_THREAD_FACTORY = new ThreadFactoryBuilder()
            .setNamePrefix("thread_pool_t").build();

    /**
     * Thread pool, all task should be submit to pool.
     */
    private static final ExecutorService POOL = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_THREADS, KEEP_ALIVE_TIME,
            TIME_UNIT, WORK_QUEUE, NAMED_THREAD_FACTORY, REJECTED_EXECUTION_HANDLER);

    public static ExecutorService getPool() {
        return POOL;
    }

}